﻿using Dapper;
using db_manage.model;
using db_manage.model.db;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Text;

namespace db_manage.dll.db
{
    /// <summary>
    /// 数据库基础操作
    /// </summary>
    public abstract class db_base
    {
        [ThreadStatic]
        private static Dictionary<string, DbConnection> db_dic; //一个线程一个连接

        public DbConnection db_connection_fast_get(db_info db_info)
        {
            if (db_dic == null)
            {
                db_dic = new Dictionary<string, DbConnection>();
            }
            var tip = db_info.db_link_info.ip + "_" + db_info.name;
            if (!db_dic.ContainsKey(tip))
            {
                db_dic.Add(tip, db_connection_get(db_info));
            }
            else if (string.IsNullOrEmpty(db_dic[tip].DataSource))
            {
                db_dic[tip] = db_connection_get(db_info);
            }
            return db_dic[tip];
        }

        /// <summary>
        /// 获取数据库连接
        /// </summary>
        /// <param name="db_info"></param>
        /// <returns></returns>
        public abstract DbConnection db_connection_get(db_info db_info);

        /// <summary>
        /// 连接测试
        /// </summary>
        public abstract void link_test(db_link_info db_link_info);

        /// <summary>
        /// 获取目标所有数据库列表
        /// </summary>
        public abstract List<db_info> db_info_list(db_link_info db_link_info);

        /// <summary>
        /// 创建记录日志表
        /// </summary>
        public abstract void db_record_create(db_info db_info);

        /// <summary>
        /// 分离并移动数据库
        /// </summary>
        public abstract void detach_move(db_info db_info, string path);

        /// <summary>
        /// 附加数据库
        /// </summary>
        /// <param name="db_Link_Info">附加数据库</param>
        /// <param name="path">附加目录</param>
        public abstract void attach(db_info db_info, string path);

        /// <summary>
        /// 备份数据库
        /// </summary>
        public abstract string bak(db_info db_info, db_bak_param db_bak_param);

        /// <summary>
        /// 检查数据库差异
        /// </summary>
        public abstract List<db_diff_info> diff_check(db_struct template_db_struct, db_info db_info);

        /// <summary>
        /// 修复数据库差异
        /// </summary>
        public abstract void diff_fix(db_info db_info, List<db_diff_info> list);

        /// <summary>
        /// 执行脚本
        /// </summary>
        public void sql_exec(db_info db_info, string sql, object param = null, int? commandTimeout = 60 * 10)
        {
            db_connection_fast_get(db_info).Execute(sql, param, null, commandTimeout);
        }

        /// <summary>
        /// 查询脚本
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="db_info"></param>
        /// <param name="sql"></param>
        public IEnumerable<T> sql_query<T>(db_info db_info, string sql, object param = null, int? commandTimeout = 60 * 10)
        {
            return db_connection_fast_get(db_info).Query<T>(sql, param, null, false, commandTimeout);
        }

        /// <summary>
        /// 查询单个数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="db_info"></param>
        /// <param name="sql"></param>
        /// <param name="param"></param>
        /// <param name="commandTimeout"></param>
        /// <returns></returns>
        public T sql_queryfirstordefault<T>(db_info db_info, string sql, object param = null, int? commandTimeout = 60 * 10)
        {
            return db_connection_fast_get(db_info).QueryFirstOrDefault<T>(sql, param, null, commandTimeout);
        }

        /// <summary>
        /// 获取最新记录
        /// </summary>
        /// <returns></returns>
        public db_manage_record last_get(db_info db_info)
        {
            var sql = "select * from db_manage_record order by vernum desc ";
            return sql_queryfirstordefault<db_manage_record>(db_info, sql);
        }

        /// <summary>
        /// 获取数据库结构
        /// </summary>
        /// <param name="db_info"></param>
        /// <returns></returns>
        public abstract db_struct db_struct_get(db_info db_info, bool is_sql = false);
    }
}
